package com.ruoyi.common.utils.sm2;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.SM2;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.sm2.KeyConstant;
import com.ruoyi.common.utils.sm2.ModeTypeConstant;
import com.ruoyi.common.utils.sm2.SecretCommon;
import com.ruoyi.framework.web.domain.AjaxResult;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 猴哥
 */
public class SM2Util {
    /**
     * get key pair
     */
    public static Map<String, String> createKeyPair() throws NoSuchAlgorithmException {
        return SecretCommon.createKeyPair();
    }

    /**
     * encrypt
     * @param plainText 需加密的明文字符串
     * @param publicKey 公钥
     */
    public static String encrypt(String plainText, String publicKey) throws IOException, InvalidCipherTextException {
        return encrypt(plainText, publicKey, ModeTypeConstant.BASE);
    }

    /**
     * encrypt
     * @param plainText 需加密的明文字符串
     * @param publicKey 公钥
     * @param modeType base:标准；bc：BC模式
     */
    public static String encrypt(String plainText, String publicKey, String modeType) throws IOException, InvalidCipherTextException {
        return SecretCommon.encrypt(plainText, publicKey, ModeTypeConstant.getMode(modeType));
    }

    /**
     * decrypt
     * @param cipherText 需加密的字符串
     * @param privateKey 私钥
     */
    public static String decrypt(String cipherText, String privateKey) throws InvalidCipherTextException, UnsupportedEncodingException {
        return decrypt(cipherText, privateKey, ModeTypeConstant.BASE);
    }

    /**
     * decrypt
     * @param cipherText 需加密的字符串
     * @param privateKey 私钥
     * @param modeType base:标准；bc：BC模式
     */
    public static String decrypt(String cipherText, String privateKey, String modeType) throws
            InvalidCipherTextException,
            UnsupportedEncodingException {
        return SecretCommon.decrypt(cipherText, privateKey, ModeTypeConstant.getMode(modeType));
    }

    /**
     * 生成秘钥对
     *
     * @return 公钥和私钥
     */
    public static Map<String, String> generator() {
        SM2 sm2 = SmUtil.sm2();
        String publicKey = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false)).toUpperCase();
        String privateKey = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey())).toUpperCase();
        return new HashMap<String, String>(2) {{
            put("publicKey", publicKey);
            put("privateKey", privateKey);
        }};
    }

    public static void main (String[] args) throws Exception {
      //{"privateKey":"7763492F5B3486717D3A1169D62A8B63B450CF0FEFDFD4220A8A6A422E35336F","publicKey":"041039DEF54C44A3469ECA06B336E63F6FA4C9A4364E7B2AF0B02FF0CA4D787AD4DB30FBA4038E9FF93F86A287BD1E4751B01A8BD4672EC6F667833E431163EFEC"}
  /*      String publicKey=
                "041039DEF54C44A3469ECA06B336E63F6FA4C9A4364E7B2AF0B02FF0CA4D787AD4DB30FBA4038E9FF93F86A287BD1E4751B01A8BD4672EC6F667833E431163EFEC";
        String privateKey="7763492F5B3486717D3A1169D62A8B63B450CF0FEFDFD4220A8A6A422E35336F";*/
          AjaxResult result = new AjaxResult();
        result.put("code","0");
        result.put("msg","成功");
        Map<String,Object> map = new HashMap <>();
        map.put("00000000000000000","000000000000000");
        result.put("data",map);


        Map<String, String> createKeyPair = SM2Util.createKeyPair();
        System.out.println("秘钥对：" + createKeyPair);
        String privateKey = createKeyPair.get(KeyConstant.PRIVATE_KEY);
        String publicKey = createKeyPair.get(KeyConstant.PUBLIC_KEY);
        String encrypt = SM2Util.encrypt(JSONObject.toJSONString(result), KeyConstant.PUBLIC_KEY);
        System.out.println("加密后密文：" + encrypt);
        String decrypt = SM2Util.decrypt(encrypt, KeyConstant.PRIVATE_KEY);
        System.out.println("解密后明文：" + decrypt);

        /*Map <String, String> generator = Sm2Util.generator();
        System.out.println(JSONObject.toJSONString(generator));*/
    }
}
